Fix GtkStatusIcon to not take up space on the panel if it is invisible.
authorMatthias Clasen <mclasen@redhat.com>
Sat, 27 Jan 2007 05:51:19 +0000 (05:51 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Sat, 27 Jan 2007 05:51:19 +0000 (05:51 +0000)
2007-01-27  Matthias Clasen  <mclasen@redhat.com>

        * gtk/gtkstatusicon.c:
        * gtk/gtktrayicon-x11.c: Fix GtkStatusIcon to not
        take up space on the panel if it is invisible.  (340110, Christian
        Persch)

        * tests/teststatusicon.c:
        * tests/Makefile.am: Updates

svn path=/trunk/; revision=17224

ChangeLog
gtk/gtkstatusicon.c
gtk/gtktrayicon-x11.c
tests/Makefile.am
tests/teststatusicon.c

index a38322636cbb2f8841a4e46c33563cc5a4d497d5..81b1aa64d59e10d839f912a1f6d02eedde57fc7c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-01-27  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkstatusicon.c:
+       * gtk/gtktrayicon-x11.c: Fix GtkStatusIcon to not
+       take up space on the panel if it is invisible.  (340110, Christian
+       Persch)
+
+       * tests/teststatusicon.c:
+       * tests/Makefile.am: Updates
+
 2007-01-27  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkfilesel.h:
index 44d3798e59ae3907a2600e9fad2208766db18d6d..418db4a43564c202d1227effb77d4067d9e90e7c 100755 (executable)
@@ -130,6 +130,9 @@ struct _GtkStatusIconPrivate
   guint         visible : 1;
 };
 
+static GObject* gtk_status_icon_constructor      (GType                  type,
+                                                  guint                  n_construct_properties,
+                                                  GObjectConstructParam *construct_params);
 static void     gtk_status_icon_finalize         (GObject        *object);
 static void     gtk_status_icon_set_property     (GObject        *object,
                                                  guint           prop_id,
@@ -162,6 +165,7 @@ gtk_status_icon_class_init (GtkStatusIconClass *class)
 {
   GObjectClass *gobject_class = (GObjectClass *) class;
 
+  gobject_class->constructor  = gtk_status_icon_constructor;
   gobject_class->finalize     = gtk_status_icon_finalize;
   gobject_class->set_property = gtk_status_icon_set_property;
   gobject_class->get_property = gtk_status_icon_get_property;
@@ -478,13 +482,11 @@ gtk_status_icon_init (GtkStatusIcon *status_icon)
                            G_CALLBACK (gtk_status_icon_screen_changed), status_icon);
   priv->image = gtk_image_new ();
   gtk_container_add (GTK_CONTAINER (priv->tray_icon), priv->image);
+  gtk_widget_show (priv->image);
 
   g_signal_connect_swapped (priv->image, "size-allocate",
                            G_CALLBACK (gtk_status_icon_size_allocate), status_icon);
 
-  gtk_widget_show (priv->image);
-  gtk_widget_show (priv->tray_icon);
-
   status_icon->priv->tooltips = gtk_tooltips_new ();
   g_object_ref_sink (priv->tooltips);
 #endif
@@ -541,6 +543,30 @@ gtk_status_icon_init (GtkStatusIcon *status_icon)
 #endif 
 }
 
+static GObject*
+gtk_status_icon_constructor (GType                  type,
+                             guint                  n_construct_properties,
+                             GObjectConstructParam *construct_params)
+{
+  GObject *object;
+  GtkStatusIcon *status_icon;
+  GtkStatusIconPrivate *priv;
+  
+  object = G_OBJECT_CLASS (gtk_status_icon_parent_class)->constructor (type,
+                                                                       n_construct_properties,
+                                                                       construct_params);
+
+#ifdef GDK_WINDOWING_X11
+  status_icon = GTK_STATUS_ICON (object);
+  priv = status_icon->priv;
+  
+  if (priv->visible)
+    gtk_widget_show (priv->tray_icon);
+#endif
+
+  return object;
+}
+
 static void
 gtk_status_icon_finalize (GObject *object)
 {
@@ -1651,8 +1677,10 @@ gtk_status_icon_set_visible (GtkStatusIcon *status_icon,
 #ifdef GDK_WINDOWING_X11
       if (visible)
        gtk_widget_show (priv->tray_icon);
-      else
+      else if (GTK_WIDGET_REALIZED (priv->tray_icon)) {
        gtk_widget_hide (priv->tray_icon);
+       gtk_widget_unrealize (priv->tray_icon);
+      }
 #endif
 #ifdef GDK_WINDOWING_WIN32
       if (priv->nid.hWnd != NULL)
index 16d8bc35c7356a3ca6446246ac4921f7d4f45613..826e31963846c0bdd2b32eed43bddca7dfc168e5 100755 (executable)
@@ -72,8 +72,7 @@ static gboolean gtk_tray_icon_delete    (GtkWidget   *widget,
 static gboolean gtk_tray_icon_expose    (GtkWidget      *widget, 
                                         GdkEventExpose *event);
 
-static void gtk_tray_icon_update_manager_window    (GtkTrayIcon *icon,
-                                                   gboolean     dock_if_realized);
+static void gtk_tray_icon_update_manager_window    (GtkTrayIcon *icon);
 static void gtk_tray_icon_manager_window_destroyed (GtkTrayIcon *icon);
 
 G_DEFINE_TYPE (GtkTrayIcon, gtk_tray_icon, GTK_TYPE_PLUG)
@@ -213,19 +212,31 @@ gtk_tray_icon_manager_filter (GdkXEvent *xevent,
       xev->xclient.message_type == icon->priv->manager_atom &&
       xev->xclient.data.l[1] == icon->priv->selection_atom)
     {
-      gtk_tray_icon_update_manager_window (icon, TRUE);
+      GTK_NOTE (PLUGSOCKET,
+               g_print ("GtkStatusIcon %p: tray manager appeared\n", icon));
+
+      gtk_tray_icon_update_manager_window (icon);
     }
   else if (xev->xany.window == icon->priv->manager_window)
     {
       if (xev->xany.type == PropertyNotify &&
          xev->xproperty.atom == icon->priv->orientation_atom)
        {
+          GTK_NOTE (PLUGSOCKET,
+                   g_print ("GtkStatusIcon %p: got PropertyNotify on manager window for orientation atom\n", icon));
+
          gtk_tray_icon_get_orientation_property (icon);
        }
-      if (xev->xany.type == DestroyNotify)
+      else if (xev->xany.type == DestroyNotify)
        {
+          GTK_NOTE (PLUGSOCKET,
+                   g_print ("GtkStatusIcon %p: got DestroyNotify for manager window\n", icon));
+
          gtk_tray_icon_manager_window_destroyed (icon);
        }
+      else
+        GTK_NOTE (PLUGSOCKET,
+                 g_print ("GtkStatusIcon %p: got other message on manager window\n", icon));
     }
   
   return GDK_FILTER_CONTINUE;
@@ -237,6 +248,9 @@ gtk_tray_icon_unrealize (GtkWidget *widget)
   GtkTrayIcon *icon = GTK_TRAY_ICON (widget);
   GdkWindow *root_window;
 
+  GTK_NOTE (PLUGSOCKET,
+           g_print ("GtkStatusIcon %p: unrealizing\n", icon));
+
   if (icon->priv->manager_window != None)
     {
       GdkWindow *gdkwin;
@@ -245,14 +259,15 @@ gtk_tray_icon_unrealize (GtkWidget *widget)
                                               icon->priv->manager_window);
       
       gdk_window_remove_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
+
+      icon->priv->manager_window = None;
     }
 
   root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
 
   gdk_window_remove_filter (root_window, gtk_tray_icon_manager_filter, icon);
 
-  if (GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->unrealize)
-    (* GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->unrealize) (widget);
+  GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->unrealize (widget);
 }
 
 static void
@@ -289,6 +304,10 @@ gtk_tray_icon_send_manager_message (GtkTrayIcon *icon,
 static void
 gtk_tray_icon_send_dock_request (GtkTrayIcon *icon)
 {
+  GTK_NOTE (PLUGSOCKET,
+           g_print ("GtkStatusIcon %p: sending dock request to manager window %x\n",
+                    icon, icon->priv->manager_window));
+
   gtk_tray_icon_send_manager_message (icon,
                                      SYSTEM_TRAY_REQUEST_DOCK,
                                      icon->priv->manager_window,
@@ -297,14 +316,22 @@ gtk_tray_icon_send_dock_request (GtkTrayIcon *icon)
 }
 
 static void
-gtk_tray_icon_update_manager_window (GtkTrayIcon *icon,
-                                    gboolean     dock_if_realized)
+gtk_tray_icon_update_manager_window (GtkTrayIcon *icon)
 {
   Display *xdisplay;
-  
+
+  g_return_if_fail (GTK_WIDGET_REALIZED (icon));
+
+  GTK_NOTE (PLUGSOCKET,
+           g_print ("GtkStatusIcon %p: updating tray icon manager window, current manager window: %x\n",
+                    icon, icon->priv->manager_window));
+
   if (icon->priv->manager_window != None)
     return;
 
+  GTK_NOTE (PLUGSOCKET,
+           g_print ("GtkStatusIcon %p: trying to find manager window\n", icon));
+
   xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
   
   XGrabServer (xdisplay);
@@ -323,33 +350,40 @@ gtk_tray_icon_update_manager_window (GtkTrayIcon *icon,
     {
       GdkWindow *gdkwin;
 
+      GTK_NOTE (PLUGSOCKET,
+               g_print ("GtkStatusIcon %p: is being managed by window %x\n",
+                               icon, icon->priv->manager_window));
+
       gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
                                              icon->priv->manager_window);
       
       gdk_window_add_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
 
-      if (dock_if_realized && GTK_WIDGET_REALIZED (icon))
-       gtk_tray_icon_send_dock_request (icon);
+      gtk_tray_icon_send_dock_request (icon);
 
       gtk_tray_icon_get_orientation_property (icon);
     }
+  else
+    GTK_NOTE (PLUGSOCKET,
+             g_print ("GtkStatusIcon %p: no tray manager found\n", icon));
 }
 
 static void
 gtk_tray_icon_manager_window_destroyed (GtkTrayIcon *icon)
 {
+  GtkWidget *widget = GTK_WIDGET (icon);
   GdkWindow *gdkwin;
-  
+
+  g_return_if_fail (GTK_WIDGET_REALIZED (icon));
   g_return_if_fail (icon->priv->manager_window != None);
 
-  gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
-                                         icon->priv->manager_window);
-      
-  gdk_window_remove_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
+  GTK_NOTE (PLUGSOCKET,
+           g_print ("GtkStatusIcon %p: tray manager window destroyed\n", icon));
 
-  icon->priv->manager_window = None;
+  gtk_widget_hide (widget);
+  gtk_widget_unrealize (widget);
 
-  gtk_tray_icon_update_manager_window (icon, TRUE);
+  gtk_widget_show (widget);
 }
 
 static gboolean 
@@ -359,17 +393,14 @@ gtk_tray_icon_delete (GtkWidget   *widget,
   GtkTrayIcon *icon = GTK_TRAY_ICON (widget);
   GdkWindow *gdkwin;
 
-  if (icon->priv->manager_window != None)
-    {  
-      gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
-                                             icon->priv->manager_window);
-      
-      gdk_window_remove_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
-      
-      icon->priv->manager_window = None;
-    }
+  GTK_NOTE (PLUGSOCKET,
+           g_print ("GtkStatusIcon %p: delete notify, tray manager window %x\n",
+                    icon, icon->priv->manager_window));
+
+  gtk_widget_hide (widget);
+  gtk_widget_unrealize (widget);
 
-  gtk_tray_icon_update_manager_window (icon, TRUE);  
+  gtk_widget_show (widget);
 
   return TRUE;
 }
@@ -384,8 +415,14 @@ gtk_tray_icon_realize (GtkWidget *widget)
   char buffer[256];
   GdkWindow *root_window;
 
-  if (GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->realize)
-    GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->realize (widget);
+  GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->realize (widget);
+
+  GTK_NOTE (PLUGSOCKET,
+           g_print ("GtkStatusIcon %p: realized, window: %x, socket window: %x\n",
+                    widget,
+                    GDK_WINDOW_XWINDOW (widget->window),
+                    GTK_PLUG (icon)->socket_window ?
+                            GDK_WINDOW_XWINDOW (GTK_PLUG (icon)->socket_window) : 0));
 
   screen = gtk_widget_get_screen (widget);
   display = gdk_screen_get_display (screen);
@@ -408,8 +445,7 @@ gtk_tray_icon_realize (GtkWidget *widget)
                                              "_NET_SYSTEM_TRAY_ORIENTATION",
                                              False);
 
-  gtk_tray_icon_update_manager_window (icon, FALSE);
-  gtk_tray_icon_send_dock_request (icon);
+  gtk_tray_icon_update_manager_window (icon);
 
   root_window = gdk_screen_get_root_window (screen);
   
index d9458dfd953dfa882318386c734904e9d7aac95a..6972165a0356180a03adbd151fd6f23f00560465 100644 (file)
@@ -247,6 +247,7 @@ testspinbutton_SOURCES =            \
        testspinbutton.c
 
 teststatusicon_SOURCES =       \
+       prop-editor.c           \
        teststatusicon.c
 
 testmerge_SOURCES =            \
index 1256152e97e14f4e1e6df9258f711e56cc0127a5..9fe9c99c5dc601b8d8e28c0943cc857ed0bd0fb4 100755 (executable)
@@ -22,6 +22,7 @@
  */
 
 #include <gtk/gtk.h>
+#include "prop-editor.h"
 
 typedef enum
 {
@@ -56,6 +57,13 @@ orientation_changed_cb (GtkStatusIcon *icon)
   g_print ("status icon %p orientation changed to %d\n", icon, orientation);
 }
 
+static void
+screen_changed_cb (GtkStatusIcon *icon)
+{
+  g_print ("status icon %p screen changed to %p\n", icon,
+          gtk_status_icon_get_screen (icon));
+}
+
 static void
 update_icons (void)
 {
@@ -215,6 +223,20 @@ check_activated (GtkCheckMenuItem *item)
   gtk_status_icon_set_screen (GTK_STATUS_ICON (icons->data), screen);
 }
 
+static void
+do_properties (GtkMenuItem   *item,
+              GtkStatusIcon *icon)
+{
+       static GtkWidget *editor = NULL;
+
+       if (editor == NULL) {
+               editor = create_prop_editor (G_OBJECT (icon), GTK_TYPE_STATUS_ICON);
+               g_signal_connect (editor, "destroy", G_CALLBACK (gtk_widget_destroyed), &editor);
+       }
+
+       gtk_window_present (GTK_WINDOW (editor));
+}
+
 static void
 do_quit (GtkMenuItem *item)
 {
@@ -255,6 +277,13 @@ popup_menu (GtkStatusIcon *icon,
 
   gtk_widget_show (menuitem);
 
+  menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PROPERTIES, NULL);
+  g_signal_connect (menuitem, "activate", G_CALLBACK (do_properties), icon);
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+
+  gtk_widget_show (menuitem);
+
   menuitem = gtk_menu_item_new_with_label ("Quit");
   g_signal_connect (menuitem, "activate", G_CALLBACK (do_quit), NULL);
 
@@ -263,7 +292,8 @@ popup_menu (GtkStatusIcon *icon,
   gtk_widget_show (menuitem);
 
   gtk_menu_popup (GTK_MENU (menu), 
-                 NULL, NULL, NULL, NULL, 
+                 NULL, NULL,
+                 gtk_status_icon_position_menu, icon,
                  button, activate_time);
 }
 
@@ -290,6 +320,7 @@ main (int argc, char **argv)
       g_signal_connect (icon, "size-changed", G_CALLBACK (size_changed_cb), NULL);
       g_signal_connect (icon, "notify::embedded", G_CALLBACK (embedded_changed_cb), NULL);
       g_signal_connect (icon, "notify::orientation", G_CALLBACK (orientation_changed_cb), NULL);
+      g_signal_connect (icon, "notify::screen", G_CALLBACK (screen_changed_cb), NULL);
       g_print ("icon size %d\n", gtk_status_icon_get_size (icon));
       gtk_status_icon_set_blinking (GTK_STATUS_ICON (icon), FALSE);
 
@@ -301,6 +332,8 @@ main (int argc, char **argv)
 
       icons = g_slist_append (icons, icon);
  
+      update_icons ();
+
       timeout = gdk_threads_add_timeout (2000, timeout_handler, icon);
     }